package FanXingT;

import FanXingT.fclass.Apple;
import FanXingT.fclass.Basket;
import FanXingT.fclass.Fruit;
import FanXingT.fclass.Orange;
import org.apache.log4j.Logger;
import org.junit.Test;

/**
 * @author Ajie
 * @date 2022/11/24
 * @function Java的数组为什么不支持泛型？
 * 编译器不允许创建带泛型的数组实例，但允许数组引用类型中出现泛型
 *     Basket<Fruit>[] fruitBasket = new Basket <Fruit> [10];//编译器：Generic array creation !
 *     Basket<Fruit>[] fruitBasket = new Basket [10];//编译器：OK
 *
 */
public class ArraysFanXing {
    private static final Logger logger = Logger.getLogger(ArraysFanXing.class);

    public static void main(String[] args) {
    }

    //声明泛型数组
    @Test
    public void generitArraysT(){
//        Basket<Fruit>[] fruitBasket = new Basket <Fruit> [10];//编译器：Generic array creation !
        Basket<Fruit>[] fruitBasket = new Basket [10];//编译器：OK

//        fruitBasket[0] = new Basket <Apple>();//编译器：Required type : Basket<Fruits provided : Basket<Apple>
//        fruitBasket[1]= "not a fruit !";//编译器：Required type : Basket< Fruit> Provided :java.lang.String
        fruitBasket[2] = new Basket<Fruit> ();
    }


    //协变  类。泛型不变
    @Test
    public void xieBian() {
        logger.info("xieBian: ");
//        Fruit array = new Apple[10];//编译 Error,java: 不兼容的类型: Apple[]无法转换为 Fruit
//        Fruit array = new Fruit[10];//编译 Error,java: 不兼容的类型: Fruit[]无法转换为 Fruit
//        Fruit[] array = new Fruit[10];//OK
        Fruit[] array = new Apple[10];//OK, 协变。 eg:List --> ArrayList
        System.out.println("ArraysFanXing:xieBian: array instanceof Apple[]:"+(array instanceof Apple[]));//true
        logger.info("xieBian: array instanceof Fruit[]:"+( array instanceof Fruit[]));//true
        logger.info("xieBian: array instanceof Object[]:"+(array instanceof Object[]));//true
        logger.info("xieBian:  array instanceof Orange[]:"+( array instanceof Orange[]));//false .世纪类型判断
    }

    //破坏泛型安全
    @Test
    public void brokenTSafe() {
      System.out.println("brokenTSafe:");

//    编译：OK！
//    运行：java.lang.ArrayStoreException: java.lang.String
    Basket<Fruit> [] fruitBasket = new Basket[10];
    Object[] objs = fruitBasket; // Basket[]是Object[]的子类型
//    objs[0] = "not a fruit !";
    }



}
